-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[RISCV] Add Qualcomm uC Xqcilsm (Load Store Multiple) extension #119823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This extension adds 6 instructions that can do multi-word load/store. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support.
|
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-risc-v Author: Sudharsan Veeravalli (svs-quic) ChangesThis extension adds 6 instructions that can do multi-word load/store. The current spec can be found at: This patch adds assembler only support. Full diff: https://github.com/llvm/llvm-project/pull/119823.diff 14 Files Affected:
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index c268f75a0fd8df..715d9e414e6114 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -191,6 +191,7 @@
// CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
+// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-EMPTY:
// CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2867dcceb84fd7..f6a0dd4bf2383c 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -435,6 +435,9 @@ The current vendor extensions supported are:
``experimental-Xqcicsr``
LLVM implements `version 0.2 of the Qualcomm uC CSR extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
+``experimental-Xqcilsm``
+ LLVM implements `version 0.2 of the Qualcomm uC Load Store Multiple extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
+
``experimental-Xqcisls``
LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index ddee4ab8ce1b37..5d2ff17ee19848 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -223,6 +223,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load Store Multiple)
+ extension.
Changes to the WebAssembly Backend
----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 7c91dc07bbd3e5..5b9946e5132e40 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -724,6 +724,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm48() const { return IsUImm<48>(); }
bool isUImm64() const { return IsUImm<64>(); }
+ bool isUImm5NonZero() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isUImm8GE32() const {
int64_t Imm;
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -1506,6 +1516,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
case Match_InvalidUImm5:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+ case Match_InvalidUImm5NonZero:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
case Match_InvalidUImm6:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
case Match_InvalidUImm7:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b8ca32434aa43e..99017195185fd3 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -690,6 +690,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC Arithmetic custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
"Qualcomm uC Conditional Select custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32,
+ "Qualcomm uC Load Store Multiple custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 9e36d62352ae51..8b407a9fd25505 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -301,6 +301,7 @@ enum OperandType : unsigned {
OPERAND_UIMM3,
OPERAND_UIMM4,
OPERAND_UIMM5,
+ OPERAND_UIMM5_NONZERO,
OPERAND_UIMM5_LSB0,
OPERAND_UIMM6,
OPERAND_UIMM6_LSB0,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index d1922eb0262792..ebaf2a28ba881c 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1375,6 +1375,14 @@ def HasVendorXqcics
AssemblerPredicate<(all_of FeatureVendorXqcics),
"'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+def FeatureVendorXqcilsm
+ : RISCVExperimentalExtension<"xqcilsm", 0, 2,
+ "'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
+def HasVendorXqcilsm
+ : Predicate<"Subtarget->hasVendorXqcilsm()">,
+ AssemblerPredicate<(all_of FeatureVendorXqcilsm),
+ "'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 3af49d7e74460c..9a61b38cfce2d8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,13 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
+def uimm5nonzero : RISCVOp<XLenVT>,
+ ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
+ let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
+ let DecoderMethod = "decodeUImmNonZeroOperand<5>";
+ let OperandType = "OPERAND_UIMM5_NONZERO";
+}
+
def uimm11 : RISCVUImmLeafOp<11>;
//===----------------------------------------------------------------------===//
@@ -105,6 +112,26 @@ class QCISELECTICCI<bits<3> funct3, string opcodestr>
let rs1 = imm;
}
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class QCILoadMultiple<bits<2> func2, DAGOperand InTyRs2, string opcodestr>
+ : RVInstRBase<0b111, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
+ opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
+ bits<7> imm;
+ let Inst{31-25} = {func2, imm{6-2}};
+}
+
+
+// rd corresponds to the source for the store 'rs3' described in the spec.
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class QCIStoreMultiple<bits<2> func2, DAGOperand InTyRs2, string opcodestr>
+ : RVInstRBase<0b111, OPC_CUSTOM_1, (outs),
+ (ins GPR:$rd, GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
+ opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
+ bits<7> imm;
+ let Inst{31-25} = {func2, imm{6-2}};
+}
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -167,3 +194,34 @@ let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
} // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
+
+let Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm" in {
+ def QC_SWM : QCIStoreMultiple<0b00, GPRNoX0, "qc.swm">;
+ def QC_SWMI : QCIStoreMultiple<0b01, uimm5nonzero, "qc.swmi">;
+ def QC_SETWM : QCIStoreMultiple<0b10, GPRNoX0, "qc.setwm">;
+ def QC_SETWMI : QCIStoreMultiple<0b11, uimm5nonzero, "qc.setwmi">;
+
+ def QC_LWM : QCILoadMultiple<0b00, GPRNoX0, "qc.lwm">;
+ def QC_LWMI : QCILoadMultiple<0b01, uimm5nonzero, "qc.lwmi">;
+} // Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm"
+
+//===----------------------------------------------------------------------===//
+// Aliases
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXqcilsm, IsRV32] in {
+let EmitPriority = 0 in {
+ def : InstAlias<"qc.swm $rs3, $rs2, (${rs1})",
+ (QC_SWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+ def : InstAlias<"qc.swmi $rs3, $length, (${rs1})",
+ (QC_SWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
+ def : InstAlias<"qc.setwm $rs3, $rs2, (${rs1})",
+ (QC_SETWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+ def : InstAlias<"qc.setwmi $rs3, $length, (${rs1})",
+ (QC_SETWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
+ def : InstAlias<"qc.lwm $rd, $rs2, (${rs1})",
+ (QC_LWM GPRNoX0:$rd, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+ def : InstAlias<"qc.lwmi $rd, $length, (${rs1})",
+ (QC_LWMI GPRNoX0:$rd, GPR:$rs1, uimm5nonzero:$length, 0)>;
+} // EmitPriority = 0
+} // Predicates = [HasVendorXqcilsm, IsRV32]
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index de3d5564210ff4..cafc9d304e83a7 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
static constexpr StringLiteral XqciExts[] = {
- {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcisls"}};
+ {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
if (HasI && HasE)
return getIncompatibleError("i", "e");
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index cdccc712a46981..f63bc944ccf22e 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -84,6 +84,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
@@ -392,6 +393,7 @@
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
diff --git a/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s b/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s
new file mode 100644
index 00000000000000..e9aec14c3c3aa0
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s
@@ -0,0 +1,35 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcilsm -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcilsm --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.swm t0, s4, 0(gp)
+# CHECK-ENC: encoding: [0xab,0xf2,0x41,0x01]
+qc.swm x5, x20, (x3)
+
+# CHECK-INST: qc.swmi a0, 4, 0(tp)
+# CHECK-ENC: encoding: [0x2b,0x75,0x42,0x40]
+qc.swmi x10, 4, (x4)
+
+# CHECK-INST: qc.setwm tp, t5, 0(sp)
+# CHECK-ENC: encoding: [0x2b,0x72,0xe1,0x81]
+qc.setwm x4, x30, (x2)
+
+# CHECK-INST: qc.setwmi t0, 31, 0(a2)
+# CHECK-ENC: encoding: [0xab,0x72,0xf6,0xc1]
+qc.setwmi x5, 31, (x12)
+
+# CHECK-INST: qc.lwm t2, ra, 0(s4)
+# CHECK-ENC: encoding: [0x8b,0x73,0x1a,0x00]
+qc.lwm x7, x1, (x20)
+
+# CHECK-INST: qc.lwmi a3, 9, 0(s7)
+# CHECK-ENC: encoding: [0x8b,0xf6,0x9b,0x40]
+qc.lwmi x13, 9, (x23)
diff --git a/llvm/test/MC/RISCV/xqcilsm-invalid.s b/llvm/test/MC/RISCV/xqcilsm-invalid.s
new file mode 100644
index 00000000000000..c59260b5718d0b
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-invalid.s
@@ -0,0 +1,112 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcilsm < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcilsm < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: expected register
+qc.swm x5, x20, 12(20)
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.swm x5, x0, 12(x3)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.swm x5, x3
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.swm x5, x20, 45(x3)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.swm x5, x20, 12(x3)
+
+
+# CHECK: :[[@LINE+1]]:20: error: expected register
+qc.swmi x10, 4, 20(4)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.swmi x10, 4, 20
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.swmi x10, 32, 20(x4)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.swmi x10, 0, 20(x4)
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.swmi x10, 4, 45(x4)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.swmi x10, 4, 20(x4)
+
+
+# CHECK: :[[@LINE+1]]:23: error: expected register
+qc.setwm x4, x30, 124(2)
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.setwm x4, x0, 124(x2)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setwm x4, x30, 124
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.setwm x4, x30, 128(x2)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.setwm x4, x30, 124(x2)
+
+
+# CHECK: :[[@LINE+1]]:22: error: expected register
+qc.setwmi x5, 31, 12(12)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setwmi x5, 31, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the range [1, 31]
+qc.setwmi x5, 37, 12(x12)
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the range [1, 31]
+qc.setwmi x5, 0, 12(x12)
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.setwmi x5, 31, 98(x12)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.setwmi x5, 31, 12(x12)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.lwm x7, x1, 24(20)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lwm x7, x1, 24
+
+# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.lwm x0, x1, 24(x20)
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.lwm x7, x1, 46(x20)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.lwm x7, x1, 24(x20)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.lwmi x13, 9, 4(23)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lwmi x13, 9, 4
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.lwmi x0, 9, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.lwmi x13, 44, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.lwmi x13, 0, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.lwmi x13, 9, 77(x23)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.lwmi x13, 9, 4(x23)
diff --git a/llvm/test/MC/RISCV/xqcilsm-valid.s b/llvm/test/MC/RISCV/xqcilsm-valid.s
new file mode 100644
index 00000000000000..4893e074df327c
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-valid.s
@@ -0,0 +1,35 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcilsm -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcilsm --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.swm t0, s4, 12(gp)
+# CHECK-ENC: encoding: [0xab,0xf2,0x41,0x07]
+qc.swm x5, x20, 12(x3)
+
+# CHECK-INST: qc.swmi a0, 4, 20(tp)
+# CHECK-ENC: encoding: [0x2b,0x75,0x42,0x4a]
+qc.swmi x10, 4, 20(x4)
+
+# CHECK-INST: qc.setwm tp, t5, 124(sp)
+# CHECK-ENC: encoding: [0x2b,0x72,0xe1,0xbf]
+qc.setwm x4, x30, 124(x2)
+
+# CHECK-INST: qc.setwmi t0, 31, 12(a2)
+# CHECK-ENC: encoding: [0xab,0x72,0xf6,0xc7]
+qc.setwmi x5, 31, 12(x12)
+
+# CHECK-INST: qc.lwm t2, ra, 24(s4)
+# CHECK-ENC: encoding: [0x8b,0x73,0x1a,0x0c]
+qc.lwm x7, x1, 24(x20)
+
+# CHECK-INST: qc.lwmi a3, 9, 4(s7)
+# CHECK-ENC: encoding: [0x8b,0xf6,0x9b,0x42]
+qc.lwmi x13, 9, 4(x23)
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index cf06ec5670346e..bef3f571b174d3 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1117,6 +1117,7 @@ Experimental extensions
xqcia 0.2
xqcics 0.2
xqcicsr 0.2
+ xqcilsm 0.2
xqcisls 0.2
Supported Profiles
|
lenary
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but please wait for Craig to approve as well.
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This extension adds 6 instructions that can do multi-word load/store.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest
This patch adds assembler only support.